const ReactDOM = { render }
import Component from '../react/component'
/**
 * 
 * @param {*} vnode ReactDOM.render的第一个参数  为node节点
 * @param {*} container ReactDOM.render的第二个参数  为container容器
 */
function render(vnode, container) {
    console.log("1")
    return container.appendChild(_render(vnode))
}
function createCompontent(comp, props) {
    let inst
    //如果comp是类组件
    if (comp.prototype && comp.prototype.render) {
        inst = new comp
    } else {
        //函数组件 要构造成类组件
        inst = new Component(props)
        inst.constructor = comp
        inst.render = function () {
            return this.constructor(props)
        }
    }
    return inst
}
function setComponent(comp, props) {
    //组件将要渲染之前
    if(!comp.base){//如果comp.base存在并且comp.componentWillMount
        if(comp.componentWillMount) comp.componentWillMount() //直接调用
    }else if(comp.componentWillReceiveProps){
        comp.componentWillReceiveProps()
    }
    //设置组件的属性
    comp.props = props
    //渲染组件
    renderComponent(comp)
}
//渲染组件
 export function renderComponent(comp) {
    console.log(comp.render())
    let base = _render(comp.render())

    if(comp.base&&comp.componentWillUpdate){
        comp.componentWillUpdate()
    }
    if(comp.base){
        if(comp.componentDidUpdate){
            comp.componentDidUpdate()
        }
    }else if(comp.componentDidMount){
        comp.componentDidMount()
    }

    //节点替换
    if(comp.base&&comp.base.parentNode){
        console.log("223")
        comp.base.parentNode.replaceChild(base,comp.base)
    }
    comp.base = base
}

function _render(vnode) {
    
    //判断 vnode是否存在 若不存在直接return
    if (vnode === undefined || vnode === null || vnode === 'boolean') return
    //判断传入的vnode是否为一个字符串类型  如果是的直接渲染
    //如果传递过来的是一个数字 强制转换成string
    if(typeof vnode =='number') vnode=String(vnode)
    console.log(typeof vnode)
    if (typeof (vnode) == 'string') {
        const textnode = document.createTextNode(vnode)
        return textnode
    }
   
    //如果tag是一个函数则渲染组件
    if (typeof vnode.tag == 'function') {
        //1.创建组件
        const comp = createCompontent(vnode.tag, vnode.attrs)
        console.log(comp)
        //2.设置组件的属性
        setComponent(comp, vnode.attrs)
        //3.组件渲染的节点对象返回
        return comp.base
    }
    //dom存在
    const { tag, attrs, children } = vnode
    const tagele = document.createElement(tag)
    if (attrs) {
        Object.keys(attrs).map(key => {
            const value = attrs[key]
            setSttribute(key, value, tagele)
        })
    }
    //递归渲染子节点
    if(children){
        children.forEach(element => render(element, tagele))
        return tagele
    }
  
}
//设置标签上的属性
function setSttribute(key, value, tagele) {
    //将className变为class
    if (key == 'className') {
        key = 'class'
    }
    if (/on\w/.test(key)) {
        key=key.toLowerCase() //将事件里面的大写字母变为小写字母
        tagele[key] = value || ''
    } else if (key == 'style') {
        if (!value || typeof value === 'string') {
            tagele.style.cssText = value || ''
        } else if (value && typeof value == 'object') {
            for (let k in value) {
                if (typeof value[k] === 'number') {
                    tagele.style[k] = value[k] + 'px'
                } else {
                    tagele.style[k] = value[k]
                }
            }
        }
    } else {
        //
        if (key in tagele) {
            tagele[key] = value || ''
        }
        //值存在 更新
        if (value) {
            tagele.setAttribute(key, value)
        } else {
            tagele.removeAttribute(key)
        }
    }
}
export default ReactDOM